package com.dykj.fireFighting.web.base.analysis.controller;


import com.dykj.fireFighting.api.base.analysis.dto.AssessmentDto;
import com.dykj.fireFighting.api.base.devHisResult.entity.DevHisResult;
import com.dykj.fireFighting.api.base.devHisResult.service.IDevHisResultService;
import com.dykj.fireFighting.api.base.enterprise.entity.Enterprise;
import com.dykj.fireFighting.api.base.enterprise.service.IEnterpriseService;
import com.dykj.fireFighting.api.base.maintenance.service.IUrgentMaintenanceService;
import com.dykj.fireFighting.api.base.statistic.SocialSocreVo;
import com.dykj.fireFighting.api.base.system.entity.SysDirectory;
import com.dykj.fireFighting.api.base.system.service.ISysDirectoryService;
import com.dykj.fireFighting.api.socialUnit.devHis.service.IDevHisService;
import com.dykj.fireFighting.api.socialUnit.dutymanger.service.IDutyRecordService;
import com.dykj.fireFighting.api.socialUnit.xfxg.service.IPatrolReportService;
import com.dykj.fireFighting.common.core.api.CommonResult;
import com.dykj.fireFighting.common.core.vo.LoginUserVo;
import com.dykj.fireFighting.common.core.vo.PageVo;
import com.dykj.fireFighting.web.base.shiro.ShiroUtil;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 评估
 */
@Slf4j
@Api(value = "评估指数", tags = {"评估指数接口"})
@RestController
@RequestMapping("/assessment")
public class AssessmentController {


    @DubboReference
    private IDevHisService devHisService;
    @DubboReference
    private IUrgentMaintenanceService urgentMaintenanceService;
    @DubboReference
    private IPatrolReportService iPatrolReportService;
    @DubboReference
    private IDutyRecordService iDutyRecordService;
    @DubboReference
    private IEnterpriseService iEnterpriseService;
    @DubboReference
    private IDevHisResultService devHisResultService;
    @DubboReference
    private ISysDirectoryService directoryService;


    /**
     * 根据时间区间获取社会单位的评分
     *
     * @param assessmentDto
     * @return
     * @throws Exception
     */
    @GetMapping("/list")
    public CommonResult<PageVo<SocialSocreVo>> getData(AssessmentDto assessmentDto) throws Exception {
        String start = "";
        String end = "";
        if (StringUtils.isNotBlank(assessmentDto.getResultDate())) {

            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            Calendar ca = Calendar.getInstance();
            int year = Integer.parseInt(assessmentDto.getResultDate().substring(0, 4));
            int month = Integer.parseInt(assessmentDto.getResultDate().substring(5, 7));
            // 设置年份
            ca.set(Calendar.YEAR, year);
            // 设置月份
            ca.set(Calendar.MONTH, month - 1);
            ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
            String last = format.format(ca.getTime());

            start = assessmentDto.getResultDate() + "-01 00:00:00";
            end = last + " 23:59:59";
        }
        //获取用户类型，监控中心查下辖的单位，社会单位查自己，管理员查全部社会单位
        LoginUserVo loginUserVo = ShiroUtil.getUser();
        List<Enterprise> list = iEnterpriseService.queryUnitSelect(loginUserVo.getEnterpriseId().toString());
        List<SocialSocreVo> socreVoList = new ArrayList<>();

        for (Enterprise enterprise : list) {

            DevHisResult devHisResult = devHisResultService.getUnitNum(enterprise.getId().toString(), start, end);

            SocialSocreVo socialSocreVo = new SocialSocreVo();
            socialSocreVo.setId(enterprise.getId());
            socialSocreVo.setName(enterprise.getEnterpriseName());
            /**火警率得分 */
            int fireRateScore = devHisService.getFireRateScore(start, end, enterprise.getId().toString());
            socialSocreVo.setFireRateScore(fireRateScore);

            /**火警有效复核率 */
            int fireYXFHScore = 0;
            HashMap<String, Object> params = new HashMap<>(16);
            params.put("beginDate", start);
            params.put("endDate", end);
            params.put("unitId", enterprise.getId().toString());
            //已复核总数
            int total = devHisResult.getReviewAll();
            //有效复核数
            int effect = devHisResult.getReview();
            if (total == 0) {
                fireYXFHScore = 20;
            } else {
                double fhRate = (double) effect / total;
                if (fhRate == 1) {
                    fireYXFHScore = 20;
                }
                if (fhRate > 0.8 && fhRate < 1) {
                    fireYXFHScore = 15;
                }
                if (fhRate <= 0.8) {
                    fireYXFHScore = 0;
                }
            }
            socialSocreVo.setFireYXFHScore(fireYXFHScore);
            /**预警有效复核率20分*/
            int warnFHRate = 0;
            int watertotal = devHisResult.getManagementAll();
            if (0 == watertotal) {
                warnFHRate = 20;
            } else {
                //有效复核数
                int effectWater = devHisResult.getManagement();
                double num = (double) effectWater / (double) watertotal;
                if (num == 1) {
                    warnFHRate = 20;
                }
                if (num > 0.8 && num < 1) {
                    warnFHRate = 15;
                }
                if (num <= 0.8) {
                    warnFHRate = 0;
                }
            }
            socialSocreVo.setWarnFHRate(warnFHRate);
            /**故障率（10分）*/
            int fireGZRateScore = devHisService.getFireGZRateScore(start, end, enterprise.getId().toString());
            socialSocreVo.setFireGZRateScore(fireGZRateScore);
            /**消防安全巡查（10分）扣分制*/
            int safeSocre = iPatrolReportService.getSocre(start, end, enterprise.getId().toString());
            socialSocreVo.setSafeSocre(safeSocre);

            /**值班记录10分） 扣分制**/
            int zbScore = iDutyRecordService.getSocScore(start, end, enterprise.getId().toString());
            socialSocreVo.setZbScore(zbScore);

            /***隐患有效整改率*/
            int urgmentSocre = urgentMaintenanceService.getSociologyUrgentSocre(start, end, enterprise.getId().toString());
            socialSocreVo.setUrgmentSocre(urgmentSocre);
            int totalSocal = fireRateScore + fireYXFHScore + warnFHRate + fireGZRateScore + safeSocre + zbScore + urgmentSocre;
            socialSocreVo.setTotalScore(totalSocal);
            socreVoList.add(socialSocreVo);

        }
        //list排序
        Integer[] arr = {1};
        List<SocialSocreVo> returnSocreList = socreVoList.stream().sorted(Comparator.comparing(SocialSocreVo::getTotalScore).reversed())
                .peek(e -> e.setRanking(arr[0]++)).collect(Collectors.toList());
        if (assessmentDto.getUnitId() != null) {
            returnSocreList = returnSocreList.stream().filter(testObject -> testObject.getId().equals(assessmentDto.getUnitId())).collect(Collectors.toList());
        }
        //split page
        long page = assessmentDto.getPage();
        long limit = assessmentDto.getLimit();
        List<SocialSocreVo> subList = returnSocreList.stream().skip((page - 1) * limit).limit(limit).collect(Collectors.toList());
        PageVo<SocialSocreVo> pageVo = new PageVo<>();
        pageVo.setList(subList);
        pageVo.setTotalCount(returnSocreList.size());
        return CommonResult.success(pageVo);
    }

    /**
     * echarts数据
     *
     * @param assessmentDto
     * @return
     * @throws Exception
     */
    @GetMapping("/rankingEcharts")
    public CommonResult<PageVo<SocialSocreVo>> getRankingEchartsData(AssessmentDto assessmentDto) throws Exception {
        String start = "";
        String end = "";
        if (assessmentDto.getType() == 3) {
            if (StringUtils.isNotBlank(assessmentDto.getResultDate())) {
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                Calendar ca = Calendar.getInstance();
                int year = Integer.parseInt(assessmentDto.getResultDate().substring(0, 4));
                int month = Integer.parseInt(assessmentDto.getResultDate().substring(5, 7));
                // 设置年份
                ca.set(Calendar.YEAR, year);
                // 设置月份
                ca.set(Calendar.MONTH, month - 1);
                ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
                String last = format.format(ca.getTime());

                start = assessmentDto.getResultDate() + "-01 00:00:00";
                end = last + " 23:59:59";
            }
        } else if (assessmentDto.getType() == 2) {
            if (StringUtils.isNotBlank(assessmentDto.getResultDate())) {
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                Calendar ca = Calendar.getInstance();
                int year = Integer.parseInt(assessmentDto.getResultDate().substring(0, 4));
                int month = Integer.parseInt(assessmentDto.getResultDate().substring(5, 7));
                // 设置年份
                ca.set(Calendar.YEAR, year);
                // 设置月份
                ca.set(Calendar.MONTH, month - 1 + 2);
                ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
                String last = format.format(ca.getTime());

                start = assessmentDto.getResultDate() + "-01 00:00:00";
                end = last + " 23:59:59";
            }
        } else {
            if (StringUtils.isNotBlank(assessmentDto.getResultDate())) {
                String year = assessmentDto.getResultDate().substring(0, 4);
                start = year + "01-01 00:00:00";
                end = year + "12-31 23:59:59";
            }
        }

        //监控中心查下辖的单位，社会单位查自己，管理员查全部社会单位
        LoginUserVo loginUserVo = ShiroUtil.getUser();
        List<Enterprise> list = iEnterpriseService.queryUnitSelect(loginUserVo.getEnterpriseId().toString());
        List<SocialSocreVo> socreVoList = new ArrayList<>();

        for (Enterprise enterprise : list) {

            DevHisResult devHisResult = devHisResultService.getUnitNum(enterprise.getId().toString(), start, end);

            SocialSocreVo socialSocreVo = new SocialSocreVo();
            socialSocreVo.setId(enterprise.getId());
            socialSocreVo.setName(enterprise.getEnterpriseName());

            /**火警率得分 */
            int fireRateScore = devHisService.getFireRateScore(start, end, enterprise.getId().toString());
            socialSocreVo.setFireRateScore(fireRateScore);

            /**火警有效复核率 */
            int fireYXFHScore = 0;
            HashMap<String, Object> params = new HashMap<>(16);
            params.put("beginDate", start);
            params.put("endDate", end);
            params.put("unitId", enterprise.getId().toString());
            //已复核总数
            int total = devHisResult.getReviewAll();
            //有效复核数
            int effect = devHisResult.getReview();
            if (total == 0) {
                fireYXFHScore = 20;
            } else {
                double fhRate = (double) effect / total;
                if (fhRate == 1) {
                    fireYXFHScore = 20;
                }
                if (fhRate > 0.8 && fhRate < 1) {
                    fireYXFHScore = 15;
                }
                if (fhRate <= 0.8) {
                    fireYXFHScore = 0;
                }
            }
            socialSocreVo.setFireYXFHScore(fireYXFHScore);
            /**预警有效复核率20分*/
            int warnFHRate = 0;
            int watertotal = devHisResult.getManagementAll();
            if (0 == watertotal) {
                warnFHRate = 20;
            } else {
                //有效复核数
                int effectWater = devHisResult.getManagement();
                double num = (double) effectWater / (double) watertotal;
                if (num == 1) {
                    warnFHRate = 20;
                }
                if (num > 0.8 && num < 1) {
                    warnFHRate = 15;
                }
                if (num <= 0.8) {
                    warnFHRate = 0;
                }
            }
            socialSocreVo.setWarnFHRate(warnFHRate);
            /**故障率（10分）*/
            int fireGZRateScore = devHisService.getFireGZRateScore(start, end, enterprise.getId().toString());
            socialSocreVo.setFireGZRateScore(fireGZRateScore);
            /**消防安全巡查（10分）扣分制*/
            int safeSocre = iPatrolReportService.getSocre(start, end, enterprise.getId().toString());
            socialSocreVo.setSafeSocre(safeSocre);

            /**值班记录10分） 扣分制**/
            int zbScore = iDutyRecordService.getSocScore(start, end, enterprise.getId().toString());
            socialSocreVo.setZbScore(zbScore);

            /***隐患有效整改率*/
            int urgmentSocre = urgentMaintenanceService.getSociologyUrgentSocre(start, end, enterprise.getId().toString());
            socialSocreVo.setUrgmentSocre(urgmentSocre);
            int totalSocal = fireRateScore + fireYXFHScore + warnFHRate + fireGZRateScore + safeSocre + zbScore + urgmentSocre;
            socialSocreVo.setTotalScore(totalSocal);
            socreVoList.add(socialSocreVo);

        }
        //list排序
        //根据某个属性分组，汇总某个属性
        Integer[] arr = {1};
        List<SocialSocreVo> returnSocreList = socreVoList.stream().sorted(Comparator.comparing(SocialSocreVo::getTotalScore).reversed())
                .peek(e -> e.setRanking(arr[0]++)).collect(Collectors.toList());
        if (assessmentDto.getUnitId() != null) {
            returnSocreList = returnSocreList.stream().filter(testObject -> testObject.getId().equals(assessmentDto.getUnitId())).collect(Collectors.toList());
        }
        //split page
        long page = assessmentDto.getPage();
        long limit = assessmentDto.getLimit();
        List<SocialSocreVo> subList = returnSocreList.stream().skip((page - 1) * limit).limit(limit).collect(Collectors.toList());
        PageVo<SocialSocreVo> pageVo = new PageVo<>();
        pageVo.setList(subList);
        pageVo.setTotalCount(returnSocreList.size());
        return CommonResult.success(pageVo);
    }

    /**
     * echarts数据
     *
     * @param assessmentDto
     * @return
     * @throws Exception
     */
    @GetMapping("/areaEcharts")
    public CommonResult getAreaEchartsData(AssessmentDto assessmentDto) throws Exception {
        String start = "";
        String end = "";
        if (assessmentDto.getType() == 3) {
            if (StringUtils.isNotBlank(assessmentDto.getResultDate())) {
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                Calendar ca = Calendar.getInstance();
                int year = Integer.parseInt(assessmentDto.getResultDate().substring(0, 4));
                int month = Integer.parseInt(assessmentDto.getResultDate().substring(5, 7));
                // 设置年份
                ca.set(Calendar.YEAR, year);
                // 设置月份
                ca.set(Calendar.MONTH, month - 1);
                ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
                String last = format.format(ca.getTime());

                start = assessmentDto.getResultDate() + "-01 00:00:00";
                end = last + " 23:59:59";
            }
        } else if (assessmentDto.getType() == 2) {
            if (StringUtils.isNotBlank(assessmentDto.getResultDate())) {
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                Calendar ca = Calendar.getInstance();
                int year = Integer.parseInt(assessmentDto.getResultDate().substring(0, 4));
                int month = Integer.parseInt(assessmentDto.getResultDate().substring(5, 7));
                // 设置年份
                ca.set(Calendar.YEAR, year);
                // 设置月份
                ca.set(Calendar.MONTH, month - 1 + 2);
                ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
                String last = format.format(ca.getTime());

                start = assessmentDto.getResultDate() + "-01 00:00:00";
                end = last + " 23:59:59";
            }
        } else {
            if (StringUtils.isNotBlank(assessmentDto.getResultDate())) {
                String year = assessmentDto.getResultDate().substring(0, 4);
                start = year + "01-01 00:00:00";
                end = year + "12-31 23:59:59";
            }
        }

        //监控中心查下辖的单位，社会单位查自己，管理员查全部社会单位
        LoginUserVo loginUserVo = ShiroUtil.getUser();
        List<Enterprise> list = iEnterpriseService.queryUnitSelect(loginUserVo.getEnterpriseId().toString());
        List<SocialSocreVo> socreVoList = new ArrayList<>();

        for (Enterprise enterprise : list) {

            SysDirectory sysDirectory = directoryService.queryByCode(enterprise.getAreaCode());
            DevHisResult devHisResult = devHisResultService.getUnitNum(enterprise.getId().toString(), start, end);

            SocialSocreVo socialSocreVo = new SocialSocreVo();
            socialSocreVo.setId(enterprise.getId());
            socialSocreVo.setName(enterprise.getEnterpriseName());
            socialSocreVo.setAreaCode(enterprise.getAreaCode());
            socialSocreVo.setAreaName(sysDirectory.getValue());

            /**火警率得分 */
            int fireRateScore = devHisService.getFireRateScore(start, end, enterprise.getId().toString());
            socialSocreVo.setFireRateScore(fireRateScore);

            /**火警有效复核率 */
            int fireYXFHScore = 0;
            HashMap<String, Object> params = new HashMap<>(16);
            params.put("beginDate", start);
            params.put("endDate", end);
            params.put("unitId", enterprise.getId().toString());
            //已复核总数
            int total = devHisResult.getReviewAll();
            //有效复核数
            int effect = devHisResult.getReview();
            if (total == 0) {
                fireYXFHScore = 20;
            } else {
                double fhRate = (double) effect / total;
                if (fhRate == 1) {
                    fireYXFHScore = 20;
                }
                if (fhRate > 0.8 && fhRate < 1) {
                    fireYXFHScore = 15;
                }
                if (fhRate <= 0.8) {
                    fireYXFHScore = 0;
                }
            }
            socialSocreVo.setFireYXFHScore(fireYXFHScore);
            /**预警有效复核率20分*/
            int warnFHRate = 0;
            int watertotal = devHisResult.getManagementAll();
            if (0 == watertotal) {
                warnFHRate = 20;
            } else {
                //有效复核数
                int effectWater = devHisResult.getManagement();
                double num = (double) effectWater / (double) watertotal;
                if (num == 1) {
                    warnFHRate = 20;
                }
                if (num > 0.8 && num < 1) {
                    warnFHRate = 15;
                }
                if (num <= 0.8) {
                    warnFHRate = 0;
                }
            }
            socialSocreVo.setWarnFHRate(warnFHRate);
            /**故障率（10分）*/
            int fireGZRateScore = devHisService.getFireGZRateScore(start, end, enterprise.getId().toString());
            socialSocreVo.setFireGZRateScore(fireGZRateScore);
            /**消防安全巡查（10分）扣分制*/
            int safeSocre = iPatrolReportService.getSocre(start, end, enterprise.getId().toString());
            socialSocreVo.setSafeSocre(safeSocre);

            /**值班记录10分） 扣分制**/
            int zbScore = iDutyRecordService.getSocScore(start, end, enterprise.getId().toString());
            socialSocreVo.setZbScore(zbScore);

            /***隐患有效整改率*/
            int urgmentSocre = urgentMaintenanceService.getSociologyUrgentSocre(start, end, enterprise.getId().toString());
            socialSocreVo.setUrgmentSocre(urgmentSocre);
            int totalSocal = fireRateScore + fireYXFHScore + warnFHRate + fireGZRateScore + safeSocre + zbScore + urgmentSocre;
            socialSocreVo.setTotalScore(totalSocal);
            socreVoList.add(socialSocreVo);

        }
        //list排序
        //根据某个属性分组，汇总某个属性
        Map<String, LongSummaryStatistics> collect2 = socreVoList.stream().collect(Collectors.groupingBy(SocialSocreVo::getAreaName, Collectors.summarizingLong(SocialSocreVo::getTotalScore)));
        return CommonResult.success(collect2);
    }
}
